<?php
class JsPacker {
    private $packerFile = 'JavascriptPacker.class.php';
    private $scriptBase = '';
    private $packDir = 'Scripts';
    private static $packer = null;
    private $packName = '';
    private $scripts = array();
    private $contents = array();
    
    /**
     * 构造函数
     * @param String $scriptDir 未压缩JS文件存放目录
     * @param mixed  $files     待压缩JS文件,数组或字符串
     */
    public function __construct($scriptDir, $files=array()) {
        $this->packerFile = THIRD_CLASS_DIR . '/' . $this->packerFile;
        $this->scriptDir = $scriptDir;
        if ($files) {
            if (is_array($files)) {
                $this->addFiles($files);
            } else if (is_string($files)) {
                $this->addFile($files);
            }
        }
    }
    
    /**
     * 设置压缩输出目录
     * @param String $packDir 压缩输出目录， 从web根目录开始
     */
    public function setPackDir($packDir) {
        $this->packDir = $packDir;
    }
    
    /**
     * 添加单一待压缩文件
     * @param String $fileName
     */
    public function addFile($fileName) {
        $fileName = $this->scriptDir . '/' . $fileName;
        if(file_exists($fileName)) {
            $this->scripts[md5($fileName)] = $fileName;
        }
    }
    
    /**
     * 添加多个压缩文件
     * @param mixed $files 数组或字符串
     */
    public function addFiles($files) {
        if(is_array($files)) {
            foreach($files as $file) $this->addFile($file);
        } else {
            $this->addFile($files);
        }
    }
    
    /**
     * 压缩输出文件名
     */
    private function getPackName($scripts) {
        $packName = md5(implode('^', array_keys($this->scripts)));
        return $packName . '.js';
    }
    
    /**
     * 实例化压缩器类
     */
    private function getPacker($contents) {
        require_once($this->packerFile);
        return new JavascriptPacker($contents);
    }
    
    /**
     * 压缩代码并返回web访问路径
     */
    private function packJs() {
        $packName = $this->getPackName($this->scripts);
        foreach($this->scripts as $file) {
            $this->contents[] = file_get_contents($file);
        }
        if($this->contents) {
            $contents = implode("\n", $this->contents);
            $packer = $this->getPacker($contents);
            $packContents = $packer->pack();
            unset($packer);
            $packFile = WEBROOT_DIR . '/' . $this->packDir . '/' . $packName;
            file_put_contents($packFile, $packContents);
            return '/' . $this->packDir . '/' . $packName . '?' . filemtime($packFile);
        }
    }
    
    /**
     * 返回压缩WEB访问路径
     */
    public function toString() {
        ksort($this->scripts);
        $packName = $this->getPackName($this->scripts);
        $packFile = WEBROOT_DIR . '/' . $this->packDir . '/' . $packName;
        if (false == Config::get('DEBUG') && file_exists($packFile)) {
            return '/' . $this->packDir . '/' . $packName . '?' . filemtime($packFile);
        } else {
            return $this->packJs();
        }
    }
    
    /**
     * 魔术方法返回WEB访问路径
     */
    public function __toString() {
        return $this->toString();
    }
};
?>